#include "main.h"
#include "ParseSDT.h"
#include "ParseDescriptor.h"

void Network_Name_Descriptor(unsigned char Descriptor[204])
{
    NETWORK_NAME_DESCRIPTOR NetworkNameTable = {0};
    int NetworkNamePosition = 0;
    int NetworkName;

    printf("------------------NetworkNameDescriptor----------------\n");
    NetworkNameTable.descriptor_tag = Descriptor[NetworkNamePosition];
    NetworkNameTable.descriptor_length = Descriptor[NetworkNamePosition+1];
    
    printf("descriptor_tag = %x\n",NetworkNameTable.descriptor_tag);
    printf("descriptor_length = %x\n",NetworkNameTable.descriptor_length);

    for(int i = NetworkNamePosition+2; i < NetworkNameTable.descriptor_length; i++)
    {
        NetworkNameTable.descriptor_char[i] = Descriptor[i];
        printf("descriptor_char = %x\n",NetworkNameTable.descriptor_char[i]);
    }
}

void Service_List_Descriptor(unsigned char Descriptor[204])
{
    SERVICR_LIST_DESCRIPTOR ServiceListTable = {0};
    int ServiceListPosition = 0;
    int ServiceInfoPosition = 0;

    printf("-------------------ServiceListDescriptor----------------------\n");
    ServiceListTable.descriptor_tag = Descriptor[ServiceListPosition];
    ServiceListTable.descriptor_length = Descriptor[ServiceListPosition+1];

    printf("descriptor_tag = %x\n",ServiceListTable.descriptor_tag);
    printf("descriptor_length = %x\n",ServiceListTable.descriptor_length);

    for(int i = ServiceListPosition+2; i < ServiceListTable.descriptor_length; i += 3)
    {
        ServiceListTable.service_info[ServiceInfoPosition].service_id = Descriptor[i] << 8 | Descriptor[i+1];
        ServiceListTable.service_info[ServiceInfoPosition].service_type = Descriptor[i+2];

        printf("service_id = %x\n",ServiceListTable.service_info[ServiceInfoPosition].service_id);
        printf("service_type = %x\n",ServiceListTable.service_info[ServiceInfoPosition].service_type);  

        ServiceInfoPosition++;            
    }
}

void Stuffing_Descriptor(unsigned char Descriptor[204])
{
    STUFFING_DESCRIPTOR StuffingTable = {0};
    int StuffingPosition = 0;

    StuffingTable.descriptor_tag = Descriptor[StuffingPosition];
    StuffingTable.descriptor_length = Descriptor[StuffingPosition+1];

    for(int i = 0; i < StuffingTable.descriptor_length; i++)
    {
        StuffingTable.stuffing_byte[i] = Descriptor[StuffingPosition+2+i];       
    }

    printf("-------------------StreamIdentifierDescriptor----------------------\n");
    printf("descriptor_tag = %x\n",StuffingTable.descriptor_tag);
    printf("descriptor_length = %x\n",StuffingTable.descriptor_length);
    for(int i = 0; i < StuffingTable.descriptor_length; i++)
    {
        printf("StuffingTable.stuffing_byte[%d] = %x\n",i, StuffingTable.stuffing_byte[i]);       
    }
}

void Satellite_Delivery_System_Descriptor(unsigned char Descriptor[204])
{
    SATELLITE_DELIVERY_SYSTEM_DESCRIPTOR SatelliteDeliveryTable = {0};
    int SatelliteDeliveryPosition = 0;

    printf("-------------------SatelliteDeliveryDescriptor----------------------\n");
    SatelliteDeliveryTable.descriptor_tag = Descriptor[SatelliteDeliveryPosition];
    SatelliteDeliveryTable.descriptor_length = Descriptor[SatelliteDeliveryPosition+1];
    SatelliteDeliveryTable.frequency =  (Descriptor[SatelliteDeliveryPosition + 2] << 24) | (Descriptor[SatelliteDeliveryPosition + 3] << 16)
	        | (Descriptor[SatelliteDeliveryPosition + 4] << 8) | Descriptor[SatelliteDeliveryPosition + 5];   
    SatelliteDeliveryTable.orbital_position = (Descriptor[SatelliteDeliveryPosition+6] << 8) | (Descriptor[SatelliteDeliveryPosition+7]);
    SatelliteDeliveryTable.west_east_flag = Descriptor[SatelliteDeliveryPosition + 8] >> 7;
    SatelliteDeliveryTable.polarization = (Descriptor[SatelliteDeliveryPosition + 8] >> 5) & 0x03;
    SatelliteDeliveryTable.modulation_system = (Descriptor[SatelliteDeliveryPosition + 8] >> 2) & 0x01;
    SatelliteDeliveryTable.moudulation_type = Descriptor[SatelliteDeliveryPosition + 8] & 0x3;
    SatelliteDeliveryTable.symbol_rate = (Descriptor[SatelliteDeliveryPosition + 9] << 20) | (Descriptor[SatelliteDeliveryPosition + 10] << 12)
	        | (Descriptor[SatelliteDeliveryPosition + 11] << 4) | (Descriptor[SatelliteDeliveryPosition + 12] >> 4);
    SatelliteDeliveryTable.FEC_inner = Descriptor[SatelliteDeliveryPosition + 12] & 0x0f; 

    printf("descriptor_tag = %x\n",SatelliteDeliveryTable.descriptor_tag);
    printf("descriptor_length = %x\n",SatelliteDeliveryTable.descriptor_length);
    printf("frequency = %x\n",SatelliteDeliveryTable.frequency);
    printf("orbital_position = %x\n",SatelliteDeliveryTable.orbital_position);
    printf("west_east_flag = %x\n",SatelliteDeliveryTable.west_east_flag);
    printf("polarization = %x\n",SatelliteDeliveryTable.polarization);  

    if(SatelliteDeliveryTable.modulation_system == 1)
    {
        SatelliteDeliveryTable.roll_off = (Descriptor[SatelliteDeliveryPosition + 8] >> 3) & 0x03;
        printf("roll_off = %x\n",SatelliteDeliveryTable.roll_off);
    }else{
        SatelliteDeliveryTable.zero = (Descriptor[SatelliteDeliveryPosition + 8] >> 1) & 0x03;
        printf("zero = %x\n",SatelliteDeliveryTable.zero);
    }
    
    printf("modulation_system = %x\n",SatelliteDeliveryTable.modulation_system);
    printf("moudulation_type = %x\n",SatelliteDeliveryTable.moudulation_type);
    printf("symbol_rate = %x\n",SatelliteDeliveryTable.symbol_rate);
    printf("FEC_inner = %x\n",SatelliteDeliveryTable.FEC_inner);
    
}

void Service_Descriptor(unsigned char Descriptor[204])
{
    SERVICE_DESCRIPTOR ServiceTable = {0};
    int ServiceDespritorPosition = 0;

	ServiceTable.descriptor_tag = Descriptor[ServiceDespritorPosition];
	ServiceTable.descriptor_length = Descriptor[ServiceDespritorPosition + 1];
	ServiceTable.service_type = Descriptor[ServiceDespritorPosition + 2];
	ServiceTable.service_provider_name_length = Descriptor[ServiceDespritorPosition + 3];
	memcpy(ServiceTable.service_provider_name, Descriptor + ServiceDespritorPosition + 4,
	        ServiceTable.service_provider_name_length);
	ServiceTable.service_name_length = Descriptor[4 + ServiceTable.service_provider_name_length];
	memcpy(ServiceTable.service_name,
	        Descriptor + ServiceDespritorPosition + 5 + ServiceTable.service_provider_name_length,
	        ServiceTable.service_name_length);

    printf("-------------------ServiceDescriptor----------------------\n");
    printf("descriptor_tag = %x\n",ServiceTable.descriptor_tag);
    printf("descriptor_length = %x\n",ServiceTable.descriptor_length);
    printf("service_type = %x\n",ServiceTable.service_type);
    printf("service_provider_name_length = %x\n",ServiceTable.service_provider_name_length);
    printf("service_provider_name = %s\n",ServiceTable.service_provider_name);
    printf("service_name_length = %x\n",ServiceTable.service_name_length);
    printf("service_name = %s\n",ServiceTable.service_name);

}

void Stream_Identifier_Descriptor(unsigned char Descriptor[204])
{
    STREAM_IDENTIFIER_DESCRIPTOR StreamIdentifierTable = {0};
    int StreamIdentifierPosition = 0;

    StreamIdentifierTable.descriptor_tag = Descriptor[StreamIdentifierPosition];
    StreamIdentifierTable.descriptor_length = Descriptor[StreamIdentifierPosition+1];
    StreamIdentifierTable.component_tag = Descriptor[StreamIdentifierPosition+2];

    printf("-------------------StreamIdentifierDescriptor----------------------\n");
    printf("descriptor_tag = %x\n",StreamIdentifierTable.descriptor_tag);
    printf("descriptor_length = %x\n",StreamIdentifierTable.descriptor_length);
    printf("component_tag = %x\n",StreamIdentifierTable.component_tag);

}

void Cable_Delivery_System_Descriptor(unsigned char Descriptor[204])
{
    CABLE_DELIVERY_SYSTEM_DESCRIPTOR CableDeliverySystemTable = {0};
    int CableDeliverySystemPosition = 0;

    CableDeliverySystemTable.descriptor_tag = Descriptor[CableDeliverySystemPosition];
    CableDeliverySystemTable.descriptor_length = Descriptor[CableDeliverySystemPosition+1];
    CableDeliverySystemTable.reserved_future_use = Descriptor[CableDeliverySystemPosition+2] << 4 
                    | (Descriptor[CableDeliverySystemPosition+3] >> 4);
    CableDeliverySystemTable.frequency = (Descriptor[CableDeliverySystemPosition+3] & 0x0f << 28) 
                    | (Descriptor[CableDeliverySystemPosition+4] << 20) | (Descriptor[CableDeliverySystemPosition+5] << 12)
                    | (Descriptor[CableDeliverySystemPosition+6] << 4) | (Descriptor[CableDeliverySystemPosition+7 >> 4]);
    CableDeliverySystemTable.FEC_outer = Descriptor[CableDeliverySystemPosition+7] >> 4;
    CableDeliverySystemTable.modulationg = Descriptor[CableDeliverySystemPosition+8];
    CableDeliverySystemTable.symbol_rate = (Descriptor[CableDeliverySystemPosition+9] << 20)
                    | (Descriptor[CableDeliverySystemPosition+10] << 12) | (Descriptor[CableDeliverySystemPosition+11] << 4)
                    | (Descriptor[CableDeliverySystemPosition+12] >> 4);
    CableDeliverySystemTable.FEC_inner = (Descriptor[CableDeliverySystemPosition+12] & 0x0f << 28)
                    | (Descriptor[CableDeliverySystemPosition+13] << 20) | (Descriptor[CableDeliverySystemPosition+14] << 12)
                    | (Descriptor[CableDeliverySystemPosition+15] << 4) | (Descriptor[CableDeliverySystemPosition+16 >> 4]);
    
    printf("-------------------CableDeliverySystemDescriptor----------------------\n");
    printf("descriptor_tag = %x\n",CableDeliverySystemTable.descriptor_tag);
    printf("descriptor_length = %x\n",CableDeliverySystemTable.descriptor_length);
    printf("reserved_future_use = %x\n",CableDeliverySystemTable.reserved_future_use);
    printf("frequency = %x\n",CableDeliverySystemTable.frequency);
    printf("FEC_outer = %x\n",CableDeliverySystemTable.FEC_outer);
    printf("modulationg = %x\n",CableDeliverySystemTable.modulationg);
    printf("symbol_rate = %x\n",CableDeliverySystemTable.symbol_rate);
    printf("FEC_inner = %x\n",CableDeliverySystemTable.FEC_inner);

}

void ParseTS_Descriptor(unsigned char Descriptor[204])
{
    switch (Descriptor[0])
    {
    case 0x40:
        Network_Name_Descriptor(Descriptor);
        break;

    case 0x41:
        Service_List_Descriptor(Descriptor);
        break;

    case 0x42:
        Stuffing_Descriptor(Descriptor);
        break;

    case 0x43:
        Satellite_Delivery_System_Descriptor(Descriptor);
        break;

    case 0x44:
        Cable_Delivery_System_Descriptor(Descriptor);
        break;

    case 0x48:
        Service_Descriptor(Descriptor);
        break;
    
    case 0x52:
        Stream_Identifier_Descriptor(Descriptor);
        break;

    

    default:
        break;
    }
}